﻿using System;
using System.Text;
using System.Drawing;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public static partial class NativeAOT
{
    [UnmanagedCallersOnly(EntryPoint = "newt")]
    public static unsafe int newt(IntPtr x_ptr, double eps, IntPtr f_x_ptr, IntPtr df_x_ptr, int inter)
    {
        double* x = (double*)x_ptr.ToPointer();
        f_x = Marshal.GetDelegateForFunctionPointer<delegatefunc_x>(f_x_ptr);
        df_x = Marshal.GetDelegateForFunctionPointer<delegatefunc_x>(df_x_ptr);

        return newt(x, eps, inter);
    }

    /// <summary>
    /// 方程求根newton法
    /// f方程左端函数f(x)的函数名。
    /// df方程左端函数f(x)一阶导函数名。
    /// </summary>
    /// <param name="x">x存放方程根的初值。返回迭代终值。</param>
    /// <param name="eps">控制精度要求。</param>
    /// <param name="inter">最多迭代次数,500</param>
    /// <returns>若返回-1，则表示出现df/dx=0的情况。程序最多迭代次数为500。</returns>
    public static unsafe int newt(double* x, double eps, int inter = 500)
    {
        int k;
        double y, dy, d, p, x0, x1;

        k = 0;
        x0 = *x;
        y = f_x(x0);
        dy = df_x(x0);
        d = eps + 1.0;
        while ((d >= eps) && (k < inter))
        {
            //出现df(x)/dx=0
            //if (Math.Abs(dy) + 1.0 == 1.0)
            if (EQ0(dy))
            {
                // cout <<"dy == 0 !";
                return (-1);
            }
            // 迭代
            x1 = x0 - y / dy;
            y = f_x(x1);
            dy = df_x(x1);
            d = Math.Abs(x1 - x0);
            p = Math.Abs(y);
            if (p > d) d = p;
            x0 = x1;
            k = k + 1;
        }
        *x = x0;
        return (k);
    }

    /*
    // 方程求根newton法例
      int main()
      { 
          int k;
          double x,eps;
          double newtf(double x), newtdf(double x);
          eps=0.000001;  x=1.5;
          k=newt(&x,eps,newtf,newtdf);
          if (k>=0)
          {
              cout <<"迭代次数 = " <<k <<endl;
              cout <<"迭代终值 x = " <<x <<endl;
          }
          return 0;
      }
    // f(x)
      double newtf(double x)
      { 
          return(x*x*(x-1.0)-1.0);
      }
    // df(x)/dx
      double newtdf(double x)
      {
          return(3.0*x*x - 2.0*x);
      }
    */
}

